<?php
/**
 * <b>RUBIK IT Solution & Development ltd.</b>
 *
 * PROJECT		: Rubik Ultimate Framework
 * @version 	: 1.1
 * COPYRIGHT    : 2008
 * ------------------------------------------------------
 * 
 * Created on	:  Jun 19, 2008
 * 
 */

// no direct access
defined ( '_FW_EXEC' ) or die ( 'Restricted access' );

class AbstractRubikMappingDTO extends Object {
	
	var $_tableName;
	var $_fields;

	/**
	 * Database
	 *
	 * @var Database
	 */
	var $_db;
	
	/**
	 * Constructor
	 *
	 * @param string $tableName this is table name.
	 * @param Database $db database object of this DB Info.
	 */
	function __construct($tableName, &$db) {
		$this->_tableName = $tableName;
		$this->_db = $db;
		$this->_fields = RubikHelper::getPropertyKeys($this);
	}

	/**
	 * Set values
	 *
	 * @param array/object $arrayOrObject
	 */
	function setValues($arrayOrObject) {
		RubikHelper::bindCaseSensitve($arrayOrObject, $this);
	}
	
	/**
	 * Get the value of field contain the array.
	 *
	 */
	function getArrayValues() {
		$key1 = $this->_fields[0];
		$key2 = $this->_fields[1];
		
		$val1 = $this->$key1;
		$val2 = $this->$key2;
		
		if (!$val1 && !$val2) {
			return null;
		}
		if (is_array($val1)) {
			return $val1;
		}
		if (is_array($val2)) {
			return $val2;
		}
		
		$db = $this->_db;
		$tblName = $db->nameQuote($this->_tableName);		
		
		$key = null;
		if ($this->$key1) {
			$key = $key1;
			$key1 = $db->nameQuote($key1);
			$key2 = $db->nameQuote($key2);
			$sql = "SELECT {$key2} FROM {$tblName} WHERE {$key1}={$val1}";
		}
		else {
			$key = $key2;
			$key1 = $db->nameQuote($key1);
			$key2 = $db->nameQuote($key2);
			$sql = "SELECT {$key1} FROM {$tblName} WHERE {$key2}={$val2}";
		}
		
		$db->setQuery($sql);
		$result = $db->loadResultArray();
		$vals = array();
		foreach ($result as $val) {
			$vals[] = $val;
		}
		$this->$key = $vals;
		return $this->$key;
	}
	
	/**
	 * Bind values
	 *
	 * @param array/object $arrayOrObject
	 * @return boolean
	 */
	function bind($arrayOrObject) {
		RubikHelper::bindCaseSensitve($arrayOrObject, $this);
	}
	
	function save() {
		$key1 = $this->_fields[0];
		$key2 = $this->_fields[1];
		
		$val1 = $this->$key1;
		$val2 = $this->$key2;
		
		if (!($val1 || $val2) || (is_array($val1) && is_array($val2))) {
			return false;
		}
		$db = $this->_db;
		
		$key1 = $db->nameQuote($key1);
		$key2 = $db->nameQuote($key2);
		$tblName = $db->nameQuote($this->_tableName);
		
		if (is_array($val1)) {
			$arrSql = $this->_createDeleteInsertSQL($key2, $val2, $key1, $val1, $tblName);
		}
		else {
			$arrSql = $this->_createDeleteInsertSQL($key1, $val1, $key2, $val2, $tblName);
		}

		$db->BeginTrans();
		$db->execute($arrSql['delete']);
		if ($arrSql['insert']) {
			$db->execute($arrSql['insert']);
		}
		$db->CommitTrans();
		return true;
	}
	
	/**
	 * Create delete, insert SQL clause
	 *
	 * @param string $keyField
	 * @param string/int $keyVal
	 * @param string $arrField
	 * @param array $arrVals
	 * @param string $tblName
	 * @return array('insert'=>$insertSql, 'delete'=>$deleteSql);
	 */
	function _createDeleteInsertSQL($keyField, $keyVal, $arrField, $arrVals, $tblName) {
		$keyVal = intval($keyVal);
		$deleteSql = "DELETE FROM {$tblName} WHERE {$keyField}={$keyVal}";
		
		if (is_array($arrVals) && count($arrVals)) {
			$vals = array();
			foreach ($arrVals as $val) {
				$val  = intval($val);
				$vals[] = "({$val}, {$keyVal})";
			}
			$insertSql = "INSERT INTO {$tblName} ({$arrField}, {$keyField}) VALUES ".implode(', ', $vals);
		}
		return array('delete'=>$deleteSql, 'insert'=>$insertSql);
	}
}

class AbstractMappingDTO extends AbstractRubikMappingDTO {
	/**
	 * Constructor
	 *
	 * @param string $tableName this is table name.
	 * @param Database $db database object of this DB Info.
	 */
	function __construct($tableName, $db=null) {
		if ($db == null) {
			$db = &SysDatabase::getInstance();
		}
		parent::__construct($tableName, $db);
	}
}
?>
